package com.shenmazong.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.shenmazong.dto.TbSoftware;
import com.shenmazong.config.MqConfig;
import com.shenmazong.service.TbSoftwareService;
import com.shenmazong.mapper.TbSoftwareMapper;
import com.shenmazong.utils.ResultResponse;
import com.shenmazong.vo.BatchChooseIdVo;
import com.shenmazong.vo.ListParamVo;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.redisson.Redisson;
import org.redisson.api.LocalCachedMapOptions;
import org.redisson.api.RLocalCachedMap;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 *
 */
@Service
public class TbSoftwareServiceImpl extends ServiceImpl<TbSoftwareMapper, TbSoftware>
implements TbSoftwareService{
    @Autowired
    private TbSoftwareMapper tbSoftwareMapper;
    @Autowired
    private Redisson redisson;
    @Autowired
    private ElasticsearchRestTemplate elasticsearchRestTemplate;
    @Autowired
    private AmqpTemplate amqpTemplate;

    private ObjectMapper objectMapper=new ObjectMapper();
    @Override
    public ResultResponse findAllSoftwareAdmin(ListParamVo listParamVo) {
        NativeSearchQueryBuilder builder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.preTags("<b style='color:red;'>").postTags("</b>").field("softwareName");
        boolQuery.must(QueryBuilders.rangeQuery("deleteFlag").lte(0));
        if (!StringUtils.isEmpty(listParamVo.getParamMap().get("softwareName"))){
            boolQuery.must(QueryBuilders.multiMatchQuery(listParamVo.getParamMap().get("softwareName"),"softwareName"));
        }
        if (!StringUtils.isEmpty(listParamVo.getParamMap().get("startTime"))){
            boolQuery.must(QueryBuilders.rangeQuery("createTime").gte(listParamVo.getParamMap().get("startTime")));
        }
        if (!StringUtils.isEmpty(listParamVo.getParamMap().get("endTime"))){
            boolQuery.must(QueryBuilders.rangeQuery("createTime").lte(listParamVo.getParamMap().get("endTime")));
        }
        if (!StringUtils.isEmpty(listParamVo.getParamMap().get("audit"))){
            boolQuery.must(QueryBuilders.termQuery("softwareAudit",listParamVo.getParamMap().get("audit")));
        }
        NativeSearchQuery build = builder.withPageable(PageRequest.of(listParamVo.getCurrent()-1, listParamVo.getSize())).withQuery(boolQuery)
                .withHighlightBuilder(highlightBuilder).build();
        SearchHits<TbSoftware> hits = elasticsearchRestTemplate.search(build, TbSoftware.class);
        Page<TbSoftware> page = new Page<>();
        ArrayList<TbSoftware> list = new ArrayList<>();
        for (SearchHit<TbSoftware> hit : hits) {
            TbSoftware content = hit.getContent();
            if (hit.getHighlightField("softwareName").size()>0){
                content.setSoftwareName(hit.getHighlightField("softwareName").get(0));
            }
            list.add(content);
        }
        page.setCurrent(listParamVo.getCurrent());
        page.setSize(listParamVo.getSize());
        page.setTotal(hits.getTotalHits());
        page.setRecords(list);
        return ResultResponse.SUCCESS(page);
    }

    @Override
    public ResultResponse softwareCache(ListParamVo listParamVo) {
        RLocalCachedMap<String, String> map = redisson.getLocalCachedMap("software", LocalCachedMapOptions.defaults());
        String o = map.get("software");
        List<TbSoftware> list=null;
        if (!StringUtils.isEmpty(o)){
            try {
                list=objectMapper.readValue(o,List.class);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            return ResultResponse.SUCCESS(list);
        }
        list = tbSoftwareMapper.selectList(new QueryWrapper<TbSoftware>().lambda().eq(TbSoftware::getDeleteFlag, 0).eq(TbSoftware::getSoftwareAudit,1));
        try {
            map.put("software",objectMapper.writeValueAsString(list));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return ResultResponse.SUCCESS(list);
    }

    @Override
    public ResultResponse saveSoftware(TbSoftware tbSoftware) {
        try {
            tbSoftwareMapper.insert(tbSoftware);
            TbSoftware software = tbSoftwareMapper.selectById(tbSoftware.getSoftwareId());
            HashMap<String, String> map = new HashMap<>();
            map.put("saveSoftware",objectMapper.writeValueAsString(software));
            amqpTemplate.convertAndSend(MqConfig.BOTIAN_EXCHANGE,MqConfig.SOFTWARE_KEY,objectMapper.writeValueAsString(map));
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.FAILED();
        }
        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse updateSoftware(TbSoftware tbSoftware) {
        try {
            TbSoftware select = tbSoftwareMapper.selectById(tbSoftware.getSoftwareId());
            if (!StringUtils.isEmpty(tbSoftware.getSoftwareName())){
                select.setSoftwareName(tbSoftware.getSoftwareName());
            }
            if (!StringUtils.isEmpty(tbSoftware.getSoftwareWeb())){
                select.setSoftwareWeb(tbSoftware.getSoftwareWeb());
            }
            select.setUpdateTime(new Date());
            tbSoftwareMapper.updateById(select);
            HashMap<String, String> map = new HashMap<>();
            map.put("saveSoftware",objectMapper.writeValueAsString(select));
            amqpTemplate.convertAndSend(MqConfig.BOTIAN_EXCHANGE,MqConfig.SOFTWARE_KEY,objectMapper.writeValueAsString(map));
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.FAILED();
        }
        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse deleteSoftware(BatchChooseIdVo batchChooseIdVo) {
        if (batchChooseIdVo.getIds().size()<=0){
            return ResultResponse.FAILED("至少选择一个哟");
        }
        try {
            HashMap<String, String> map = new HashMap<>();
            for (Long id : batchChooseIdVo.getIds()) {
                tbSoftwareMapper.deleteById(id);
                map.put("delSoftware",objectMapper.writeValueAsString(id));
                amqpTemplate.convertAndSend(MqConfig.BOTIAN_EXCHANGE,MqConfig.SOFTWARE_KEY,objectMapper.writeValueAsString(map));
            }
            map.clear();
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.FAILED();
        }
        return ResultResponse.SUCCESS();
    }

    @Override
    public ResultResponse auditSoftware(BatchChooseIdVo batchChooseIdVo) {
        if (batchChooseIdVo.getIds().size()<=0){
            return ResultResponse.FAILED("至少选择一个哟");
        }
        try {
            Integer audit = (Integer) batchChooseIdVo.getParamMap().get("audit");
            HashMap<String, String> map = new HashMap<>();
            for (Long id : batchChooseIdVo.getIds()) {
                TbSoftware byId = tbSoftwareMapper.selectById(id);
                byId.setSoftwareAudit(audit.byteValue());
                tbSoftwareMapper.updateById(byId);
                map.put("auditSoftware",objectMapper.writeValueAsString(byId));
                amqpTemplate.convertAndSend(MqConfig.BOTIAN_EXCHANGE,MqConfig.SOFTWARE_KEY,objectMapper.writeValueAsString(map));
            }
        } catch (Exception e) {
            e.printStackTrace();
            return ResultResponse.FAILED();
        }
        return ResultResponse.SUCCESS();
    }
}




